package org.practice.dao;

import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.practice.model.Book;
import org.practice.util.DaoException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

@Repository(value="bookDao")
public class BookDaoImpl extends HibernateTemplate implements BookDao{
	private Map<Integer,String> queryList=new HashMap<Integer,String>();
	private static Logger logger=Logger.getLogger(BookDaoImpl.class);
	
	private SessionFactory sessionFactory;
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	@Resource//默认beanName="sessionFactory",Spring根据name去上下文中查找bean,找到后注入进来,org.hibernate.impl.SessionImpl
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	public BookDaoImpl(){
		initOrderOptions();
	}
	
	public void initOrderOptions(){
		queryList.put(BookDao.ORDER_DEFAULT, "from Book b where b.category.id=:categoryId");
		queryList.put(ORDER_NAME_ASC, "from Book b where b.category.id=:categoryId order by b.name asc");
		queryList.put(ORDER_NAME_DESC, "from Book b where b.category.id=:categoryId order by b.name desc");
		
	}
	
	/**
	 * 1)分页显示(只有表单查询条件)
	 * 2)分页查询（除表单查询条件外，还带有分页的查询条件pageIndex,pageSize）
	 * pageSize=3
	 * pageIndex 	 startRow			endRow
	 *	1				1		 2			3
	 *	2				4		 5			6
	 *	3				7		 8			9
	 * 通过参数pageIndex与pageSize--->当前页首条记录在数据库中开始位置和结束位置
	 * startRow=(pageIndex-1)*pageSize+1;
	 * endRow=startRow+(pageSize-1)--推出->endRow=pageIndex*pageSize
	 * hibernate分页查询
	 * 返回startRow,根据当前页页数和每页记录数返回当前页的首条记录在数据库里的开始位置
	 */
	private int getStartRowCurrentPage(int pageIndex, int pageSize) {
		return (pageIndex - 1) * pageSize+1;
	}
	
	/**
	 * hibernate分页查询
	 * pageIndex-->当前页页码
	 * pageSize-->每页记录数rowsPerPage
	 * pageCount-->总页数(recordCount/pageSize)
	 * recordCount-->查询出来的总记录数
	 */
	public List<?> hibernateTemplatePageQuery(StringBuffer query,final Map<String, Object> values,
			final int pageIndex,final int pageSize){
		final String queryString = query.toString();
		return (List<?>)this.execute(new HibernateCallback(){
			//Spring管理Session,没有加事务控制，Spring 根据autoCommit=true,在关闭session时提交事务
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				//session.createSQLQuery("sql");//SQL查询
				Query hibernateQuery = session.createQuery(queryString);//HQL查询
				for (String key : values.keySet()) {
					Object value = values.get(key);
					if (value instanceof Collection) {
						hibernateQuery.setParameterList(key, (Collection) value);
					} else if (value instanceof Object[]) {
						hibernateQuery.setParameterList(key, (Object[]) value);
					} else {
						hibernateQuery.setParameter(key, value);
					}
				}
				//hibernate是第一条记录是从0号位置开始的,所以这里面startRow-1,数据库是从1开始
				int startRow=getStartRowCurrentPage(pageIndex,pageSize);
				List<?> result = hibernateQuery.setFirstResult(startRow-1)
						.setMaxResults(pageSize)
						.list();
				return result;
			}
			
		});
	}
	
	public List<Book> findBookByCategoryId(Integer categoryId,
			int pageIndex, int pageSize, Integer orderBy) throws DaoException {
		StringBuffer hql=new StringBuffer(queryList.get(orderBy));
		Map<String,Object> values=new HashMap<String,Object>();
		values.put("categoryId", categoryId);
		List<Book> allBooks=(List<Book>)hibernateTemplatePageQuery(hql,values,pageIndex,pageSize);
		return allBooks;
		
	}
	
	@SuppressWarnings(value={"unchecked"})
	public int getTotalPagesByCategoryId(final Integer categoryId, final int pageSize)
			throws DaoException {
		return (Integer)this.execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {//session是个代理
				Query query=session.createQuery("select count(*) from Book b where b.category.id=?");
				query.setInteger(0, categoryId);
				List<Long> list=query.list();
				int totalRows=list.get(0).intValue();
				int totalPages=0;
				if (totalRows % pageSize == 0) {
					totalPages=totalRows / pageSize;
				} else {
					totalPages=totalRows / pageSize + 1;
				}
				return totalPages;
			}
		});
	}

	public Map<Integer, String> getOrderOptions() {
		Map<Integer, String> map = new TreeMap<Integer, String>();
		map.put(ORDER_DEFAULT, "book.order.default");
		map.put(BookDao.ORDER_NAME_ASC, "book.order.name.asc");
		map.put(ORDER_NAME_DESC, "book.order.name.desc");
		return map;
	}


}
